<div class="form-group pull-right">
  <pfng-toast-notification-list [notifications]="notifications" (onCloseSelect)="handleCloseNotification($event)"
    [showClose]="true">
  </pfng-toast-notification-list>
</div>

<div *ngIf="serviceView | async as view">
  <div class="container-fluid breadcrumb-bar">
    <div class="row">
      <ol class="breadcrumb">
        <li><a routerLink="/services">Services &amp; APIs</a></li>
        <li>{{ view.service.name }} - {{ view.service.version }}</li>
      </ol>
    </div>
  </div>

  <h1>{{ view.service.name }} - {{ view.service.version }}</h1>
  <small *ngIf="view.service.metadata">Created {{ view.service.metadata.createdOn.toString() | timeAgo }}, last update on {{
    view.service.metadata.lastUpdate | date : 'medium' }}</small>

  <div *ngIf="view.service.metadata" class="metadata-labels">
    <app-label-list [metadata]="view.service.metadata"></app-label-list>
    <button type="button" class="btn btn-link" *ngIf="hasRole('admin') || hasRoleForService('manager')"
      (click)="openEditLabels()">Edit Labels</button>
  </div>

  <div class="row">
    <div class="col-md-8">
      <h3 class="section-label">Properties</h3>
      <dl class="dl-horizontal left">
        <dt>Service Type:</dt>
        <dd>
          <span class="label label-primary" *ngIf="view.service.type === 'SOAP_HTTP'">SOAP</span>
          <span class="label label-success" *ngIf="view.service.type === 'REST'">REST</span>
          <span class="label label-warning" *ngIf="view.service.type === 'EVENT'">EVENT</span>
          <span class="label label-grpc" *ngIf="view.service.type === 'GRPC'">GRPC</span>
          <span class="label label-graph" *ngIf="view.service.type === 'GRAPHQL'">GRAPH</span>
          <span class="label label-gene" *ngIf="view.service.type === 'GENERIC_REST'">DIRECT REST</span>
          <span class="label label-gene" *ngIf="view.service.type === 'GENERIC_EVENT'">DIRECT EVENT</span>
        </dd>
        <span *ngIf="view.service.type === 'SOAP_HTTP'">
          <dt>Namespace:</dt>
          <dd><code>{{ view.service.xmlNS }}</code></dd>
        </span>
        <dt>Contracts:</dt>
        <dd>
          <span *ngIf="contracts | async as contracts$; else loadingc">
            <ng-container *ngIf="contracts$.length || view.service.type != 'GENERIC_REST'; else noContracts">
              <span *ngFor="let contract of contracts$">
                <a href="{{ getContractLink(contract) }}" target="new" title="{{ contract.name }}">
                  {{ contract.name }} {{ contract.type }} <i tooltip="Source artifact: {{ contract.sourceArtifact }}" containerClass="tooltip-break" class="glyphicon glyphicon-globe"></i>
                </a><br />
                <a *ngIf="contract.type === 'OPEN_API_SPEC' || contract.type === 'ASYNC_API_SPEC' || contract.type === 'SWAGGER'"
                  href="{{ getContractDocumentationLink(contract) }}" target="new"
                  title="{{ contract.name }}">
                  View Documentation <i class="fa fa-external-link"></i>
                </a><br
                  *ngIf="contract.type === 'OPEN_API_SPEC' || contract.type === 'ASYNC_API_SPEC' || contract.type === 'SWAGGER'" />
              </span>
            </ng-container>
            <ng-template #noContracts>No contracts attached</ng-template>
          </span>
          <ng-template #loadingc>Loading contracts...</ng-template>

          <span *ngIf="view.service.type === 'GENERIC_REST'">
            <a href="/api/resources/{{ view.service.id }}/swagger_20" target="new" alt="Swagger 2.0 spec">
              Swagger 2.0 spec <i class="glyphicon glyphicon-globe"></i>
            </a> <br />
            <a href="/api/resources/{{ view.service.id }}/openapi_30" target="new" alt="OpenAPI 3.0 spec">
              OpenAPI 3.0 spec <i class="glyphicon glyphicon-globe"></i>
            </a>
          </span>
        </dd>
        <dt>Statistics:</dt>
        <dd>
          <a [routerLink]="['/metrics/invocations', view.service.name, view.service.version]">Mocks invocations <i
              class="glyphicon glyphicon-signal"></i></a>
        </dd>
        <span *ngIf="isMCPAvailable()">
          <dt>MCP Server:</dt>
          <dd>
            <a tooltip="Copy to Clipboard" placement="top"
                (click)="copyToClipboard(formatMCPUrl('/sse'), 'MCP URL')">
              HTTP SSE Endpoint <i class="pficon pficon-optimize"></i>
            </a><br/>
            <a tooltip="Copy to Clipboard" placement="top"
               (click)="copyToClipboard(formatMCPUrl(), 'MCP URL')">
              HTTP Streamable Endpoint <i class="pficon pficon-optimize"></i>
            </a>
          </dd>
        </span>
      </dl>
    </div>
    <div class="col-md-4">
      <div class="pfng-card card-pf card-pf-accented conformance-card">
        <div class="card-pf-heading">
          <h2 class="card-pf-title">Tests</h2>
        </div>
        <div class="card-pf-body">
          <div class="row" *ngIf="serviceTestConformanceMetric | async as conformanceMetric; else loadingt">
            <div class="col-xs-7">
              <div class="conformance-index">
                <dt>Conformance index</dt>
                <app-grade-index [score]="conformanceMetric.maxPossibleScore"></app-grade-index>
              </div>
              <div style="margin-top: 5px;">
                <a href="https://microcks.io/documentation/explanations/conformance-testing/#conformance-metrics" target="_blank" rel="noopener">Learn More
                  <i class="fa fa-external-link" aria-hidden="true"></i>
                </a>
              </div>
            </div>
            <div class="col-xs-5">
              <dt>Conformance score</dt>
              <span class="conformance-score">{{ (conformanceMetric.currentScore | number:'.1-2') || '0.0' }}</span>%
              <i class="fa fa-arrow-up conformance-trend"
                [class.fa-arrow-right]="conformanceMetric.latestTrend === 'STABLE' || conformanceMetric.latestTrend === null"
                [class.fa-arrow-up]="conformanceMetric.latestTrend === 'UP' || conformanceMetric.latestTrend === 'LOW_UP'"
                [class.fa-arrow-down]="conformanceMetric.latestTrend === 'DOWN' || conformanceMetric.latestTrend == 'LOW_DOWN'"
                [class.fa-low-up]="conformanceMetric.latestTrend === 'LOW_UP'"
                [class.fa-low-down]="conformanceMetric.latestTrend === 'LOW_DOWN'"></i>
            </div>
          </div>
          <ng-template #loadingt>Loading test conformance metric... You may need to update your service
            first.</ng-template>
          <div class="row" *ngIf="view.service.type != 'GENERIC_REST'" style="margin-top: 10px">
            <div class="col-sm-6" style="padding-top: 8px;">
              <a [routerLink]="['/tests/service', view.service.id]"><i class="glyphicon glyphicon-time"></i> View Tests
                Runs</a>
            </div>
            <div class="col-sm-6">
              <button class="btn btn-primary pull-right" (click)="gotoCreateTest()">
                <span class="fa fa-plus"></span> New Test
              </button>
            </div>
          </div>
        </div>
      </div>
      <span *ngIf="view.service.type === 'GENERIC_REST'">
        <p>
          You may have already used this Direct API to record resources.<br />
          Check <a (click)="openResources()">what's in the repository <i class="glyphicon glyphicon-transfer"></i></a>.
        </p>
      </span>
    </div>
  </div>

  <div>
    <h3 class="section-label">Operations
      <div class="pull-right" style="padding-right: 20px">
        <span class="spinner spinner-sm spinner-inline" style="vertical-align: text-bottom;" *ngIf="isAIEnrichInProgress()"></span>
        <button class="btn btn-warning" (click)="enrichWithAICopilot()" *ngIf="allowAICopilotOnSamples()" [disabled]="isAIEnrichInProgress()">
          <span class="pficon pficon-optimize"></span> AI Copilot
        </button>&nbsp;
        <button class="btn btn-default" (click)="openManageSamples()" *ngIf="!hasAICopilotSamples()">
          <span class="fa fa-filter"></span> Manage Samples
        </button>

        <div class="btn-group" *ngIf="hasAICopilotSamples()">
          <span class="dropdown" dropdown>
            <button class="btn btn-default dropdown-toggle" dropdownToggle aria-controls="dropdown-actions">
              <span class="fa fa-filter"></span> Manage Samples
              <span class="caret"></span>
            </button>
            <ul id="dropdown-actions" *dropdownMenu class="dropdown-menu dropdown-menu-right" aria-labelledby="exportOptions">
              <li role="presentation" (click)="openManageSamples()"><a class="filter-field dropdown-item">All Samples</a></li>
              <li role="presentation" (click)="openManageAISamples()"><a class="filter-field dropdown-item">AI Copilot only</a></li>
            </ul>
          </span>
        </div>
      </div>
    </h3>
  </div>

  <div class="container-fluid">
    <pfng-list id="operationsList" [config]="operationsListConfig" [expandTemplate]="operationDetailTemplate"
        [items]="operations!" [itemTemplate]="operationTemplate">

      <ng-template #operationTemplate let-item="item" let-index="index">
        <div class="list-pf-left">
        </div>
        <div class="list-pf-content-wrapper">
          <div class="list-pf-main-content">
            <div class="list-pf-title">{{ item.name }}</div>
            <div class="list-pf-description text-overflow-pf">
              <span [ngSwitch]="item.method">
                <span class="label label-success" *ngSwitchCase="'GET'">GET</span>
                <span class="label label-primary" *ngSwitchCase="'PUT'">PUT</span>
                <span class="label label-danger" *ngSwitchCase="'DELETE'">DELETE</span>
                <span class="label label-warning" *ngSwitchCase="'POST'">POST</span>
                <span class="label label-info" *ngSwitchDefault>{{ item.method || 'POST'}}</span>
              </span>
              <span *ngIf="item.dispatcher">
                with <code>{{ item.dispatcher }}</code> dispatcher
              </span>
            </div>
          </div>
          <div class="list-pf-additional-content">
            <div>
              <span class="pficon pficon-image"> </span>
              <strong> {{ view.messagesMap[item.name].length }}</strong> sample(s)
            </div>
          </div>

          <div class="list-view-pf-actions">
            <div class="dropdown pull-right dropdown-kebab-pf" dropdown *ngIf="allowOperationsPropertiesEdit()">
              <button id="dropdownKebabRight" class="btn btn-link dropdown-toggle" type="button" dropdownToggle aria-controls="dropdown-actions">
                <span class="fa fa-ellipsis-v"></span>
              </button>
              <ul id="dropdown-actions" *dropdownMenu class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownKebabRight">
                <li><a [routerLink]="['operation', item.name]">Edit Properties</a></li>
                <li><a (click)="openGenerateSamples(item.name)" *ngIf="allowAICopilotOnSamples()">AI Copilot Samples <i
                      class="pficon pficon-optimize"></i></a></li>
              </ul>
            </div>
          </div>
        </div>
      </ng-template>

      <ng-template #operationDetailTemplate let-item="item" let-index="index">
        <div class="row" style="display: flex; flex-wrap: nowrap;">
          <!-- Main Content Column -->
          <div [style.flex]="'1 1 auto'" style="padding-right: 40px;">
            <h4 class="section-label no-margin-top">Dispatching Properties</h4>
            <div class="dispatching-container">
              <div class="dispatching-column">
                <dl class="dl-horizontal left">
                  <span *ngIf="view.service.type === 'SOAP_HTTP'">
                    <dt>SOAP Action:</dt>
                    <dd><code>{{ item.action }}</code></dd>
                  </span>
                  <span *ngIf="!isEventTypeService()">
                    <dt>Dispatcher:</dt>
                    <dd><code>{{ item.dispatcher }}</code> &nbsp;
                      <span class="learn-more-inline">
                        <a href="https://microcks.io/documentation/explanations/dispatching/" target="_blank" rel="noopener">Learn More
                          <i class="fa fa-external-link" aria-hidden="true"></i>
                        </a>
                      </span>
                    </dd>
                    <dt>Dispatching rules:</dt>
                    <dd><code class="code-block">{{ item.dispatcherRules }}</code></dd>
                  </span>
                  <span *ngIf="isEventTypeService()">
                    <dt>Frequency:</dt>
                    <dd>
                      {{ item.defaultDelay || 0 }} s
                      <span class="label label-default async-mock-status-label" *ngIf="!isAsyncMockEnabled(item)">Mocks are
                        disabled</span>
                    </dd>
                    <dt>Available bindings:</dt>
                    <dd>
                      {{ getBindingsList(item) }} &nbsp;
                      <span class="learn-more-inline">
                        <a href="https://microcks.io/documentation/references/artifacts/asyncapi-conventions/#bindings" target="_blank" rel="noopener">Learn More
                          <i class="fa fa-external-link" aria-hidden="true"></i>
                        </a>
                      </span>
                    </dd>
                  </span>
                </dl>
              </div>
              <div class="dispatching-column">
                <dl class="dl-horizontal left" *ngIf="isEventTypeService()">
                  <span *ngIf="hasBinding(item, 'KAFKA')">
                    <dt>Kafka endpoint:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('KAFKA') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'MQTT')">
                    <dt>MQTT endpoint:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('MQTT') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'WS')">
                    <dt>WebSocket endpoint:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('WS') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'NATS')">
                    <dt>NATS endpoint:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('NATS') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'AMQP')">
                    <dt>AMQP endpoint:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('AMQP') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'GOOGLEPUBSUB')">
                    <dt>Google PubSub project:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('GOOGLEPUBSUB') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'SQS')">
                    <dt>Amazon SQS region:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('SQS') }}</a></dd>
                  </span>
                  <span *ngIf="hasBinding(item, 'SNS')">
                    <dt>Amazon SNS region:</dt>
                    <dd><a>{{ asyncAPIFeatureEndpoint('SNS') }}</a></dd>
                  </span>
                </dl>
                <dl class="dl-horizontal left" *ngIf="!isEventTypeService()">
                  <span
                    *ngIf="view.service.type === 'SOAP_HTTP' || view.service.type === 'GRPC' || view.service.type === 'GRAPHQL'">
                    <dt>Input / Output Name:</dt>
                    <dd><code>{{ item.inputName }} / {{ item.outputName }}</code></dd>
                  </span>
                  <dt *ngIf="view.service.type != 'GRAPHQL'">HTTP Verb:</dt>
                  <dd *ngIf="view.service.type != 'GRAPHQL'">
                    <div [ngSwitch]="item.method">
                      <span class="label label-success" *ngSwitchCase="'GET'">GET</span>
                      <span class="label label-primary" *ngSwitchCase="'PUT'">PUT</span>
                      <span class="label label-danger" *ngSwitchCase="'DELETE'">DELETE</span>
                      <span class="label label-warning" *ngSwitchCase="'POST'">POST</span>
                      <span class="label label-info" *ngSwitchDefault>{{ item.method || 'POST'}}</span>
                    </div>
                  </dd>
                  <dt>Default delay:</dt>
                  <dd>{{ item.defaultDelay || 0 }} ms with <code>{{ item.defaultDelayStrategy || 'fixed' }}</code> strategy</dd>
                </dl>
              </div>
            </div>
            <dl class="dl-horizontal left" *ngIf="view.service.type === 'GENERIC_REST'">
              <dt>Mock URL:</dt>
              <dd>
                <div class="input-group">
                  <input type="text" class="form-control" value="{{ formatMockUrl(item, null, null) }}" disabled />
                  <span class="input-group-addon">
                    <i class="fa fa-paste" tooltip="Copy to Clipboard" placement="top"
                      (click)="copyToClipboard(formatMockUrl(item, null, null))"></i>
                  </span>
                </div>
              </dd>
            </dl>

            <h4 class="section-label" *ngIf="item.parameterConstraints && item.parameterConstraints.length > 0">Parameter
              Constraints</h4>
            <div class="row" *ngIf="item.parameterConstraints && item.parameterConstraints.length > 0">
              <div class="col-md-6">
                <dl class="dl-horizontal left">
                  <span *ngFor="let constraint of item.parameterConstraints">
                    <span *ngIf="constraint.in === 'query'">
                      <dt>Query param {{ constraint.name }}:</dt>
                      <dd [innerHTML]="displayParameterConstraint(constraint)"></dd>
                    </span>
                  </span>
                </dl>
              </div>
              <div class="col-md-6">
                <dl class="dl-horizontal left">
                  <span *ngFor="let constraint of item.parameterConstraints">
                    <span *ngIf="constraint.in === 'header'">
                      <dt>Header {{ constraint.name }}:</dt>
                      <dd [innerHTML]="displayParameterConstraint(constraint)"></dd>
                    </span>
                  </span>
                </dl>
              </div>
            </div>

            <h4 class="section-label" *ngIf="view.service.type != 'GENERIC_REST'">Mocks</h4>
            <app-exchanges-tabset [item]="item" [view]="view" [resolvedServiceView]="resolvedServiceView"
              [notificationService]="notificationService" [isEventTypeService]="isEventTypeService"
              [getExchangeName]="getExchangeName" [getExchangeSourceArtifact]="getExchangeSourceArtifact"
              [hasBinding]="hasBinding" [getBindingProperty]="getBindingProperty" [formatMockUrl]="formatMockUrl"
              [formatAsyncDestination]="formatAsyncDestination" [getDestinationOperationPart]="getDestinationOperationPart"
              [formatRequestContent]="formatRequestContent" [formatGraphQLVariables]="formatGraphQLVariables"
              [prettyPrintIfJSON]="prettyPrintIfJSON" [formatCurlCmd]="formatCurlCmd" [copyToClipboard]="copyToClipboard"
              [removeVerbInUrl]="removeVerbInUrl" [encodeUrl]="encodeUrl" [urlType]="urlType"
              [activeExchangeName]="activeExchangeName"
              [asyncAPIFeatureEndpoint]="asyncAPIFeatureEndpoint" [config]="config"></app-exchanges-tabset>
          </div>

          <!-- Collapsible Live Traces Component -->
          <app-collapsible-live-traces
            [serviceName]="view.service.name"
            [operationName]="item.name">
          </app-collapsible-live-traces>
        </div>
      </ng-template>

    </pfng-list>
  </div>
</div>
